/*
 * State.cpp
 *
 *  Created on: 04-01-2011
 *      Author: Piotr
 */

#include "biology/State.hpp"
#include "utils/RangedValue.hpp"
#include "utils/Randomizer.hpp"

const float State::HUNGER_MAX_VALUE = 100.0f;
const float State::THIRST_MAX_VALUE = 100.0f;
const float State::LIBIDO_MAX_VALUE = 100.0f;
const float State::LIFE_MAX_VALUE = 100.0f;
const float State::HUNGRY_BORDER = 0.2f;
const float State::THIRST_BORDER = 0.2f;
const float State::LIBIDO_BORDER = 0.6f;
const float State::DRINKING_SPEED = 1.0f;
const float State::EATING_SPEED = 0.8f;

State::State(const Genotype& genotype) :
	genotype(genotype), hunger(RangedValue<float> (Range<float> (0, HUNGER_MAX_VALUE))), thirst(
			RangedValue<float> (Range<float> (0, THIRST_MAX_VALUE))), libido(RangedValue<float> (Range<
			float> (0, LIBIDO_MAX_VALUE))),
			life(RangedValue<float> (Range<float> (0, HUNGER_MAX_VALUE))), lookDirection(
					static_cast<float> (Randomizer::nextInt(-1, 1)), static_cast<float> (Randomizer::nextInt(
							-1, 1)))
{
}

const Vector& State::getLookDirection() const
{
	return lookDirection;
}

void State::setLookDirection(const Vector& lookDirection)
{
	this->lookDirection = lookDirection;
}

void State::updateWithDeltaTime(float deltaTimeInSeconds)
{
	hunger.changeBy(deltaTimeInSeconds * genotype.getHungerIncreasingSpeed());
	thirst.changeBy(deltaTimeInSeconds * genotype.getThirstIncreasingSpeed());
	libido.changeBy(deltaTimeInSeconds * genotype.getLibidoIncreasingSpeed());
	life.changeBy(deltaTimeInSeconds * genotype.getLifeIncreasingSpeed());

	if(isStarved())
	{
		life.setValue(life.getRange().getMaximum());
	}
}

float State::getHungerValue() const
{
	return hunger.getValue();
}

void State::setHungerValue(float hungerValue)
{
	hunger.setValue(hungerValue);
}

void State::changeHungerValue(float amount)
{
	hunger.changeBy(amount);
}

bool State::isHungry() const
{
	return hunger.getValue() > hunger.getRange().getMaximum() * HUNGRY_BORDER;
}

float State::getThirstValue() const
{
	return thirst.getValue();
}

void State::setThirstValue(float thirstValue)
{
	thirst.setValue(thirstValue);
}

void State::changeThirstValue(float amount)
{
	thirst.changeBy(amount);
}

bool State::isThirsty() const
{
	return thirst.getValue() > thirst.getRange().getMaximum() * THIRST_BORDER;
}

float State::getLibidoValue() const
{
	return libido.getValue();
}

bool State::isMatingTime() const
{
	return libido.getValue() > libido.getRange().getMaximum() * LIBIDO_BORDER;
}

void State::setLibidoValue(float libidoValue)
{
	libido.setValue(libidoValue);
}

float State::getLifeValue() const
{
	return life.getValue();
}

void State::clearLibidoValue()
{
	libido.setValue(libido.getRange().getMinimum());
}

void State::changeLifeValue(float amount)
{
	life.setValue(life.getValue() + amount);
}

void State::setLifeValue(float lifeValue)
{
	life.setValue(lifeValue);
}

bool State::isDead() const
{
	return life.getValue() == life.getRange().getMaximum();
}

bool State::isStarved() const
{
	return (hunger.getValue() == hunger.getRange().getMaximum() || thirst.getValue()
			== thirst.getRange().getMaximum());
}
